package com.marktotop.file.service.impl;

import com.github.tobato.fastdfs.domain.fdfs.StorePath;
import com.github.tobato.fastdfs.domain.proto.storage.DownloadByteArray;
import com.github.tobato.fastdfs.service.FastFileStorageClient;
import com.marktotop.file.entity.TbFile;
import com.marktotop.file.exception.SystemErrorCode;
import com.marktotop.file.exception.SystemException;
import com.marktotop.file.service.FastdfsService;
import com.marktotop.file.service.TbFileService;
import com.marktotop.file.utils.FastdfsConfig;
import com.marktotop.file.utils.FileUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.unit.DataSize;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Date;

/**
 * @author WXLD
 * @data 2021/4/16 - 9:07
 */
@Service
@Slf4j
public class FastdfsServiceImpl implements FastdfsService {

    @Autowired
    private FastFileStorageClient storageClient;

    @Autowired
    private FastdfsConfig prop;

    @Autowired
    private TbFileService tbFileService;


    /**
     * 上传图片资源
     *
     * @param images  文件类型 支持 jpeg/ png/ bmp/ gif
     * @return
     */
    @Override
    public String uploadImage(String originName,MultipartFile images) throws SystemException{
        // 1、校验图片类型
        String contentType = images.getContentType();
        if (!prop.getAllowTypes().contains(contentType)) {
            throw new SystemException(SystemErrorCode.IMAGE_TYPE_ERROR);
        }
        // 2、校验图片内容
        try {
            BufferedImage image = ImageIO.read(images.getInputStream());
            if (image == null || image.getWidth() == 0 || image.getHeight() == 0) {
                throw new SystemException(SystemErrorCode.IMAGE_SIZE_ERROR);
            }
        } catch (IOException e) {
            // 校验文件内容失败
            throw new SystemException(SystemErrorCode.IMAGE_ERROR);
        }
        try {
            // 3、上传到FastDFS
            // 3.1、获取扩展名
            String extension = StringUtils.substringAfterLast(images.getOriginalFilename(), ".");
            // 3.2、上传
            StorePath storePath = storageClient.uploadFile(images.getInputStream(), images.getSize(), extension, null);
            // 赋值给新的 TbFile对象
            TbFile newFile = new TbFile().setFileName(originName)
                    .setFileSize(FileUtil.getSize(images))
                    .setFileType(extension)
                    .setFileUrl(prop.getBaseUrl() + storePath.getFullPath())
                    .setDownloadNum(0)
                    .setCreateTime(new Date());
            //4、存储到数据库
            Boolean saveResult = tbFileService.saveFileInfo(newFile);
            if(saveResult != true){
                return null;
            }
            return prop.getBaseUrl() + storePath.getFullPath();
        } catch (IOException e) {
            throw new SystemException(SystemErrorCode.FILE_UPLOAD_ERROR);
        }
    }


    /**
     * 上传文件
     *     文件类型 无论什么格式，但有大小限制，100M之内
     * @param originName
     * @param file
     * @return
     * @throws SystemException
     */
    @Override
    public String uploadFile(String originName,MultipartFile file) throws SystemException {
        StorePath storePath = null;
        // 1、获取扩展名
        String extension = StringUtils.substringAfterLast(file.getOriginalFilename(), ".");
        try {
            // 上传到FastDFS
            // 上传
            storePath = storageClient.uploadFile(file.getInputStream(), file.getSize(), extension, null);
        } catch (IOException e) {
            throw new SystemException(SystemErrorCode.FILE_SIZE_ERROR);
        }
        // 返回路径
        // 赋值给新的 TbFile对象
        TbFile newFile = new TbFile().setFileName(originName)
                .setFileSize(FileUtil.getSize(file))
                .setFileType(extension)
                .setFileUrl(prop.getBaseUrl() + storePath.getFullPath())
                .setDownloadNum(0)
                .setCreateTime(new Date());
        //4、存储到数据库
        Boolean uploadResult = tbFileService.saveFileInfo(newFile);
        if (uploadResult != true){
            return null;
        }
        return prop.getBaseUrl() + storePath.getFullPath();
    }


    /**
     * 下载文件
     * exmaple: http://192.168.183.128:8888/group1/M00/00/01/rBAEtF1ESveAJIrtAATb0rfoOcM166.jpg
     * @param fileUrl 传入file全路径
     * @return
     * @throws IOException
     */
    @Override
    public byte[] downloadFile(String fileUrl) throws IOException {
        //以“/”切割4次
        String[] ss = fileUrl.split("/", 5);
        DownloadByteArray downloadByteArray = new DownloadByteArray();
        byte[] bytes = storageClient.downloadFile(ss[3], ss[4], downloadByteArray);
        return bytes;
    }


    /**
     * 删除文件
     * @param deleteFile 删除文件对象
     * @return
     * @throws SystemException
     */
    @Override
    public int deleteFile(TbFile deleteFile) throws SystemException{
        //拿到删除文件对象里的fileUrl，以“/”切割4次
        String fileUrl = deleteFile.getFileUrl();
        String[] ss = fileUrl.split("/", 5);
        try {
            // FastDFS 删除服务
            storageClient.deleteFile(ss[3], ss[4]);
            // 数据库 删除
            tbFileService.deleteFileInfo(deleteFile.getId());
            return 1;
        } catch (Exception e) {
            throw new SystemException(SystemErrorCode.FILE_DELETE_ERROR);
        }
    }

}
